from abc import ABC, abstractmethod

from chernc.treediff.gumtree.matchers.configuration_options import ConfigurationOptions
from chernc.treediff.gumtree.matchers.gumtree_properties import GumtreeProperties

class Configurable(ABC):
    """
    A configurable interface that allows the configuration of options via a GumtreeProperties object.
    """

    @abstractmethod
    def configure(self, properties: GumtreeProperties):
        """
        Default configure method that does nothing.
        Should be overridden by subclasses to make use of the provided GumtreeProperties object.
        """
        pass

    def get_applicable_options(self):
        """
        Return the set of applicable options for the object.
        Default implementation returns an empty set.
        """
        return set()

    def set_option(self, option: ConfigurationOptions, value: object):
        """
        Modify the provided option to the provided value. Raise an exception
        if the provided option is not in the set of applicable options.
        """
        if option not in self.get_applicable_options():
            raise ValueError(f"Option {option} is not allowed. Applicable options are: {self.get_applicable_options()}")

        properties = GumtreeProperties()
        properties.put(option, value)
        self.configure(properties)
